'''
【基础函数·处理时间】
GetCurrentTime(input('输入需要查找的年-月-日'), Mode=str)
（给一个2024-6-8字符串，转换为datetime对象）
输入datetime对象
查找本地节气文件后，
输出干支历法
Mode=str，return输出字符串；Mode=int，输出list[int]，供程序使用

'''

import datetime
from constants import GAN, ZHI, KONG_WANG
from core.extract.extract_format import extract_int_from_text
from core.extract.format_time import parse_datetime
from core.time.ganzhidate import GanZhiDate

# seasonal_equinox_data
# https://jieqi.txcx.com/jieqi-2054.html
# 从这个网站复制来的

'''辅助函数：用于完善info'''


def get_time_info(time_dict: dict) -> str:
    '''
    int时间转汉字干支四值，空亡地支
    :param time_dict: 至少包含 'm', 'dg', 'd' 三个键
    :return: {'time_info':str(如：甲辰年子月庚戌日午时空亡寅卯),'empty':int(空亡的第一个地支)}
    '''
    # 检查 m、dg 和 d 是否都存在且不为 None
    required_keys = ['m', 'dg', 'd']
    if not all(time_dict.get(key) is not None for key in required_keys):
        raise ValueError('日月不明')

    mg, hg = None, None

    if time_dict.get('yg') is not None:
        _1 = GAN[time_dict['yg'] % 10]
        month = time_dict['m'] if time_dict['m'] >= 3 else time_dict['m'] + 12
        # 甲己之年丙作首，乙庚之岁戊为头。丙辛之岁寻庚上，丁壬壬位顺行流。更有戊癸何处起，甲寅之上好追求。
        x0_lst = [-2, 0, 2, 4, 6]
        x0 = x0_lst[time_dict['yg'] % 5]
        mg = (month + x0) % 10  # 确定月干，month + gan
        _3 = GAN[mg]
    else:
        _1, _3 = '', ''

    _2 = _1 + ZHI[time_dict['y'] % 12] + '年' if time_dict.get('y') is not None else ''
    _4 = _3 + ZHI[time_dict['m'] % 12] + '月'
    _5 = GAN[time_dict['dg'] % 10] + ZHI[time_dict['d'] % 12] + '日'

    if time_dict.get('h') is not None:
        hour = time_dict['h'] if time_dict['h'] >= 1 else time_dict['h'] + 12
        # 甲己还加甲，乙庚丙作初，丙辛从戊起，丁壬庚子居，戊癸何方发？壬子是真途。
        x0_lst = [8, 0, 2, 4, 6]
        x0 = x0_lst[time_dict['dg'] % 5]
        hg = (hour + x0) % 10  # 确定时干，hour + gan
        _6 = GAN[hg] + ZHI[time_dict['h'] % 12] + '时'
    else:
        _6 = ''

    ric_gan_gap = time_dict['d'] - time_dict['dg'] if time_dict.get('dg') else time_dict['d'] - 10  # 癸亥日，0-0，变成首位的“戌亥”
    empty = KONG_WANG[(ric_gan_gap + 12) % 12 // 2]

    # 如果hg，mg不为None，作为键值对加入result
    time_list = [_ for _ in [_2, _4, _5, _6] if _]

    result = {'time_info': ' '.join(time_list) + f'（空亡:{empty}）', 'empty': ZHI.index(empty[0])}
    if hg is not None:
        result['hg'] = hg
    if mg is not None:
        result['mg'] = mg

    return result


def adjust_to_hour_z(dt, hour_z):
    # 检查hour_z是否在0到11之间
    if hour_z < 0 or hour_z > 11:
        raise ValueError("hour_z must be between 0 and 11")
    start_hour = (21 + 2 * hour_z) % 24
    end_hour = (23 + 2 * hour_z) % 24
    current_hour = dt.hour

    # 判断当前时间是否在指定的时辰内
    if hour_z == 1:
        # 子时特殊处理，跨天
        in_zone = current_hour >= start_hour or current_hour < end_hour
    else:
        in_zone = start_hour <= current_hour < end_hour

    # 已经在指定时辰内，无需调整
    if in_zone:
        return dt

    # 计算目标小时和需要调整的天数
    if current_hour >= end_hour:
        # 当天已经过了该时辰，退到当天的start_hour days_back = 0
        target_time = dt.replace(hour=end_hour - 1)
    else:
        # 当天还没到该时辰，退到前一天的start_hour
        days_back = 1
        target_time = dt.replace(hour=end_hour - 1) - timedelta(days=days_back)

    return target_time


'''农历时间 ===> datetime ===> info'''


def parse_lunar_2_ganzhi(string):
    '''农历转换，指定日期'''
    from lunardate import LunarDate
    dt = datetime.datetime.strptime(string, '%Y-%m-%d')
    dt = LunarDate.fromSolarDate(string)


'''阳历时间 ===> info'''


def get_current_ganzhi(hour=None) -> dict:
    '''返回当前时间的词典，你可以指定回退到刚刚过去的某个时辰hour(0-11)'''
    now = datetime.datetime.now()
    if hour is not None and isinstance(hour, int) and 0 <= hour <= 11:
        now = adjust_to_hour_z(now, hour)
    return _handle_datetime(now, hour)


def parse_datetime_2_ganzhi(date_time_str: str, hour=None):
    '''
    :param hour: 指定当天的某个时辰
    :return:
    '''
    dt = parse_datetime(date_time_str)
    return _handle_datetime(dt, hour)


def _handle_datetime(dt: datetime, hour=None):
    _dict = GanZhiDate.convert(dt, int, given_hour=hour, isMoreDetail=True)
    return GanZhiDate(**_dict).toDict(isWhole=True)


'''干支年月日时 ===> info'''


def handle_time_string(string) -> dict:
    """string 允许空值，默认为当前时间"""
    string = string.strip()

    # 没有日月，或者为空，无效输入，默认启用现在时间
    if not string or all(n not in string for n in '月日时'):
        return get_current_ganzhi()

    time_dict = extract_int_from_text(string)

    isHaveYear = all(time_dict.get(item) is not None for item in ['y', 'yg', 'd'])
    isHaveHour = time_dict['h'] is not None
    isHaveMonthDate = all(time_dict.get(item) is not None for item in ['m', 'dg', 'd'])

    if isHaveYear and isHaveMonthDate:
        gan_zhi_date = GanZhiDate(**time_dict)
        time_dict['current_time'] = gan_zhi_date.toSolarDate().strftime('%Y-%m-%d')
        time_dict.update(gan_zhi_date.toDict(isWhole=True))
        return time_dict
    elif isHaveMonthDate:
        time_dict.update(get_time_info(time_dict))
        return time_dict
    elif isHaveHour:
        return get_current_ganzhi(time_dict['h'])
    else:
        return get_current_ganzhi()

    # 不允许用户输入数字 如 3 10 12，代表寅月癸亥日


if __name__ == '__main__':

    # usage GetCurrentTime (str)
    text = get_current_ganzhi()
    print(text)

    # usage GetCurrentTime (int)
    time_dict = GetCurrentTime()
    li = ['yg-年干', 'y-年支', 'm-月建', 'mj-月将', 'dg-日干', 'd-日辰', 'h-时辰', 'msg-其他']
    for string in li:
        k, name = string.split('-')
        print(name, time_dict[k], end=';')
    print('')

    while True:
        text = GetCurrentTime(input('输入需要查找的年-月-日'), Mode=str)
        print(text)
